package com.levi.utils;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.text.TextUtils;

import com.levi.utils.log.LogUtils;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;

/**
 * 统跳
 * Created by Levi on 2018/3/22.
 */

public class ActivityRouter {
    private static final String TAG = "ActivityRouter";

    public static final String ROUTER_KEY = "router://activity/";
    private static final String FLAG = "flag";
    private static final int REQUEST_CODE_INVALID = -1;

    private static final HashMap<String, String> ROUTER_MAP = new HashMap<>();

    public static void initRouterMap(HashMap<String, String> map) {
        ROUTER_MAP.clear();
        ROUTER_MAP.putAll(map);
    }

    public static void addRouterAddress(String key, String command) {
        ROUTER_MAP.put(key, command);
    }

    public static void route(@NonNull Activity activity, @NonNull String command) {
        route(activity, command, REQUEST_CODE_INVALID);
    }

    public static void route(@NonNull Activity activity, @NonNull String command, int requestCode) {
        Intent intent = getIntent(activity.getPackageName(), command);
        if (intent == null) {
            return;
        }
        try {
            if (requestCode == -1) {
                activity.startActivity(intent);
            } else {
                activity.startActivityForResult(intent, requestCode);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void route(@NonNull Fragment fragment, @NonNull String command) {
        route(fragment, command, REQUEST_CODE_INVALID);
    }

    public static void route(@NonNull Fragment fragment, @NonNull String command, int requestCode) {
        Intent intent = getIntent(fragment.getContext().getPackageName(), command);
        if (intent == null) {
            return;
        }
        try {
            if (requestCode == -1) {
                fragment.startActivity(intent);
            } else {
                fragment.startActivityForResult(intent, requestCode);
            }
        } catch (Exception e) {
            LogUtils.e(TAG, e);
        }
    }

    /**
     * 获取统跳intent
     *
     * @param packageName
     * @param command
     * @return
     */
    private static Intent getIntent(String packageName, String command) {
        LogUtils.i(TAG, String.format("packageName: %s\ncommand: %s", packageName, command));
        if (!TextUtils.isEmpty(command) && command.startsWith(ROUTER_KEY)) {
            final String key = getCommandKey(command);
            if (!TextUtils.isEmpty(key) && ROUTER_MAP.containsKey(key)) {
                Intent intent = new Intent();
                intent.setClassName(packageName, ROUTER_MAP.get(key));
                HashMap<String, String> params = getParams(command);
                int flag = -1;
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    if (FLAG.equals(entry.getKey())) {
                        flag = Integer.parseInt(entry.getValue());
                        continue;
                    }
                    intent.putExtra(entry.getKey(), URLDecoder.decode(entry.getValue()));
                }
                if (flag != -1) {
                    intent.setFlags(flag);
                }
                return intent;
            }
        }
        return null;
    }

    /**
     * 获取统跳中的参数
     *
     * @param command
     * @return
     */
    private static HashMap<String, String> getParams(String command) {
        HashMap<String, String> params = new HashMap<>();
        try {
            params = new HashMap<>();
            Uri uri = Uri.parse(command);
            Set<String> keys = uri.getQueryParameterNames();
            for (String key : keys) {
                String value = uri.getQueryParameter(key);
                params.put(key, value);
            }
        } catch (Exception e) {
            LogUtils.e(TAG, e);
        }
        return params;
    }

    /**
     * 获取统跳key
     *
     * @param command
     * @return
     */
    private static String getCommandKey(String command) {
        try {
            Uri uri = Uri.parse(command);
            String path = uri.getPath();
            return path.substring(path.indexOf("/") + 1);
        } catch (Exception e) {
            LogUtils.e(TAG, e);
        }
        return null;
    }


    public static class CommandBuilder {
        private HashMap<String, String> mParams;
        private String mCommandKey;

        public CommandBuilder(@NonNull String commandKey) {
            mParams = new HashMap<>();
            mCommandKey = commandKey;
        }

        public CommandBuilder addParam(String key, Object obj) {
            if (key != null && obj != null) {
                mParams.put(key, obj.toString());
            }
            return this;
        }

        public String buildCommand() {
            StringBuilder command = new StringBuilder(ROUTER_KEY);
            command.append(mCommandKey);
            StringBuilder paramSb = new StringBuilder();
            for (Map.Entry<String, String> entry : mParams.entrySet()) {
                if (paramSb.length() > 0) {
                    paramSb.append("&");
                }
                paramSb.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue()));
            }
            if (paramSb.length() > 0) {
                command.append("?").append(paramSb.toString());
            }
            return command.toString();
        }
    }


    public static void dial(@NonNull Context context, @NonNull String number) {
        try {
            Intent intent = new Intent(Intent.ACTION_DIAL);
            intent.setData(Uri.parse("tel:" + number));
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent);
        } catch (Exception e) {
            //do nothing
        }
    }

    @SuppressLint("MissingPermission")
    public static void call(@NonNull Activity activity, @NonNull String number) {
        if (!PermissionChecker.checkPermission(activity, Manifest.permission.CALL_PHONE)) {
            return;
        }
        try {
            Intent intent = new Intent(Intent.ACTION_CALL);
            intent.setData(Uri.parse("tel:" + number));
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            activity.startActivity(intent);
        } catch (Exception e) {
            //do nothing
        }
    }

    public static void sms(@NonNull Activity activity, @NonNull String number) {
        if (!PermissionChecker.checkPermission(activity, Manifest.permission.SEND_SMS)) {
            return;
        }
        try {
            Uri uri = Uri.parse("smsto:" + number);
            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            activity.startActivity(intent);
        } catch (Exception e) {
            //do nothing
        }
    }
}
